<!-- 列表 -->
<template>
    <div class="cardList" :class="loading || data.length === 0 ? 'hp100' : ''">
        <template v-if="data.length > 0 && !loading">
            <Select filterableion 
                v-if="showSelectTag && cselection" 
                :data="cselection" 
                :selectKey="selectKey" 
                :selectName="selectName" 
                @clearSelect="clearSelect" 
                @closeItem="closeItem">
            </Selection>
            <Card class="card-item" v-for="(item, index) in tableData" dis-hover :key="index">
                <div class="item-fist-line">
                    <h4 class="line-left">
                        <Checkbox
                            v-if="showCheckbox"
                            v-model="item.checked"
                            @on-change="(state) => toggleSelect(state, item, index)"
                            :disabled="item.disabled"
                        ></Checkbox>
                        <span class="no" v-show="!hiddenIndex">{{ handleProIndex(index) }}、</span>
                        <CardCell 
                            v-for="column in topLeftColumns" 
                            :key="`top-left-${column.key}`"
                            :column="column" 
                            :item="item"
                            :index="index"
                        >
                        </CardCell>
                    </h4>
                    <div class="line-right">
                        <div class="extra-info flex">
                            <CardCell 
                                v-for="column in topRightColumns"
                                :key="`top-right-${column.key}`"
                                :column="column" 
                                :item="item"
                                :index="index">
                            </CardCell>
                        </div>
                        <!-- 操作按钮 -->
                        <div class="action">
                            <CardCell
                                v-for="(column) in actionColumns"
                                :key="`action-${column.key}`"
                                :index="index"
                                :item="item"
                                :column="column"
                                :action="true"
                            >
                            </CardCell>
                        </div>
                    </div>
                </div>
                <div class="item-infos" v-if="bottomColumns.length > 0">
                    <CardCell 
                        v-for="(column,index) in bottomColumns"
                        :key="`bot-render-${column.key || index}`"
                        :column="column" 
                        :item="item"
                        :index="index">
                    </CardCell>
                </div>
            </Card>
            <Page
                v-if="showPage && total > 0"
                ref="page"
                class="flex-center"
                :total="total"
                :page-size="curSize"
                :current="curPage"
                show-elevator
                show-total
                @on-change="changePage"
            />
        </template>
        <template v-if="data.length == 0 || loading">
            <NoData :loading="loading" :text="text"> </NoData>
        </template>
        <Modal v-model="htmlModal.show" :z-index="4000" :width="600" title="描述" footer-hide class-name="fix-height-modal">
            <div v-html="htmlModal.content" style="font-size:14px;" class="html-content ql-editor"></div>
        </Modal>
    </div>
</template>

<script>
import { debounce } from '@/libs/utils';
import CardCell from './cardCell.vue'
import Selection from './selection.vue'
import { mapMutations, mapState } from 'vuex';
import NoData from '@/components/common/no-data';
export default {
    name: 'CardList',
    props: {
        data: {
            type: Array,
            default: () => [],
        },
        columns: {
            type: Array,
            default: () => [],
        },
        total: {
            type: Number,
            default: 0,
        },
        page: {
            type: Number,
            default: 1,
        },
        pageSize: {
            type: Number,
            default: 10,
        },
        // showCheckbox: {
        //     type: Boolean,
        //     default: false,
        // },
        disabledCheck: {
            type: [Boolean,Function],
            default: false,
        },
        text: {
            type: String,
            default: '暂无信息',
        },
        hiddenIndex: {
            type: Boolean,
            default: false,
        },
        loading: {
            type: Boolean,
            default: false,
        },
        selectKey:{
            type: String,
            default: 'id',
        },
        selection:{ // 需要
            type: Array,
            default: () => [],
        },
        showSelectTag:{
            type:Boolean,
            default:false
        },
        selectName:{
            type: [String, Function],
            default: 'name'
        },
        selectPage:{
            type: Boolean,
            default: false
        },
        checkAll:{
            type: Boolean,
            default: false
        }
    },
    components: { NoData, CardCell, Selection },
    provide() {
        return {
            tableRoot: this
        };
    },
    mixins: [],
    data() {
        return {
            curPage: this.page || 1,
            curSize: this.pageSize,
            cselection:[],
            needInit:true,
            htmlModal:{
                show:false,
                content:''
            }
        };
    },
    watch: {
        selection(val,oldVal){
            let csIds = this.cselection.map(item => item[this.selectKey]);
            if(val.length != this.cselection.length || val.some((v, i) => !csIds.includes(v[this.selectKey]))){
                this.initSelect(val);
            }
        },
        pageAllChecked(val){
            this.$emit('update:checkAll', val)
        },
        pageAllDisabled(val){
            this.$emit('update:checkAllDisabled', val)
        },
        page(val) {
            this.curPage = val;
        },
    },
    filters: {},
    computed: {
        showCheckbox(){
            return this.columns.filter(item => this.getShow(item)).find(item => item.type === 'selection')
        },
        tableData: function () {
            let selectIds = this.cselection.map(item => item[this.selectKey])
            return this.cselection
                ? this.data.map((d) => {
                      if (selectIds.includes(d.id)) {
                          d.checked = true;
                      }
                      if(typeof d.disabled != 'undefind'){
                        d.disabled = this.getDisabled(d)
                      }
                      return d;
                  })
                : this.data;
        },
        showColumns(){
            console.log(this.columns)
            let columns = this.columns.filter(item => this.getShow(item) && item.type !== 'index' && item.type !== 'selection');
            if(!columns.every(column => column.placement === 'top-left')){
                columns[0].placement = 'top-left';
            }
            columns.forEach(column => {
                if(!column.width){
                    column.width = ['createTime','created'].includes(column.key) ? 140 : 100
                }
            })
            return columns
        },
        bottomColumns() {
            return this.getShowColumns('bottom')
        },
        topLeftColumns() {
            let columns = this.getShowColumns('top-left')
            columns[0].width = 200;
            return columns
        },
        topRightColumns() {
            return this.getShowColumns('top-right')
        },
        actionColumns() {
            return this.getShowColumns('action')
        },
        pageSelection() {
            return this.tableData.filter(item => item.checked)
        },
        showPage() {
            return Object.keys(this.$options.propsData).includes('page');
        },
        pageAllChecked(){
            return this.tableData.every(item => item.disabled || item.checked) && this.tableData.some(item => item.checked)
        },
        pageAllDisabled(){
            return this.tableData.every(item => item.disabled)
        }
    },
    created() {
        if(this.selection.length > 0){
            this.initSelect(this.selection)
            this.needInit = false
        }
        this.columns.forEach((column) => {
            if (!column.placement) {
                this.$set(column, 'placement', 'bottom');
            }
            if (column.render) {
                this.$set(column, 'type', 'render');
            }
            if (column.type === 'html'){
                column.fun = this.showHtml;
            }
            if (column.action || column.key == 'action' || column.slot == 'action'){
                column.placement = 'action'
            }
        });
    },
    mounted() {
        this.$emit('update:checkAllDisabled', this.pageAllDisabled)
        this.$emit('update:checkAll', this.pageAllChecked)
        this.setPagination();
        this.debounceResize = debounce(this.setPagination, 1000);
        window.addEventListener('resize', this.debounceResize);
    },
    beforeDestroy() {
        window.removeEventListener('resize', this.debounceResize);
    },
    methods: {
        setPagination(height) {
            let _this = this;
            //40:头部，45:分页
            const pageHeight = 34 + 10; //this.$refs.page.$el.clientHeight; 分页
            const itemHeight = 96;
            this.contentHeight = this.$el.clientHeight - pageHeight;
            let pageSize = Math.max(Math.floor(this.contentHeight / itemHeight), 1);
            let usePage = this.curPage,
                maxPage;
            if (this.total > 0) {
                maxPage = Math.ceil(this.total / pageSize);
                usePage = Math.min(this.curPage, maxPage);
            }
            if (pageSize === this.pageSize && this.page === usePage && this.init) {
                return;
            }
            this.curSize = pageSize;
            this.curPage = usePage;
            this.$emit('update:page',usePage);
            this.$emit('update:size',pageSize);
            if(this.init){
                this.$emit('change-page',usePage);
            }
            this.init = true;
        },
        initSelect(data){
            this.cselection = [...data];
            this.$emit('on-selection-change',this.selectPage ? this.pageSelection : data,this.pageAllChecked)
        },
        //清空选择
        clearSelect(){
            this.cselection = [];
            this.data.forEach(item => item.checked = false);
            this.$emit('update:selection', this.selectPage ? this.pageSelection : this.cselection);
            this.$emit('on-selection-change',this.selectPage ? this.pageSelection : this.cselection,this.pageAllChecked)
        },
        //外部关闭Tag
        closeItem(sel){
            this.toggleSelect(false,sel);
        },
        //切换选择
        toggleSelect(state, item) {
            let selectIds = this.cselection.map(item => item[this.selectKey])
            if (state) {
                //如果是选中
                if (!selectIds.includes(item.id) && !item.disabled) {
                    this.cselection.push(item);
                }
                item.checked = true;
            } else {
                //如果是取消
                let index = selectIds.findIndex((key) => key === item.id);
                if (index !== -1) {
                    this.cselection.splice(index, 1);
                }
                item.checked = false;
            }
            this.$emit('update:selection', this.selectPage ? this.pageSelection : this.cselection)
            this.$emit('on-selection-change', this.selectPage ? this.pageSelection : this.cselection, this.pageAllChecked);
        },
        // 全选/取消全选
        selectAll(status) {
            if(status){
                this.data.forEach(item => {
                    if(!item.checked && !item.disabled){
                        this.toggleSelect(true,item);
                        // item.checked = true;
                        // this.cselection.push(item);
                    }
                })
            }else{
                this.data.forEach((item) => {
                    if(item.checked){
                        this.toggleSelect(false,item);
                    }
                });
            }
            // this.$emit('update:selection', this.selectPage ? this.pageSelection : this.cselection)
            // this.$emit('on-selection-change',this.selectPage ? this.pageSelection : this.cselection,this.pageAllChecked)
        },
        // 获取
        getShowColumns(placement) {
            return this.showColumns
                .filter((column) => column.placement == placement)
                .sort((a, b) => a.order - b.order);
        },
        // 计算index
        handleProIndex(key) {
            if (this.page && this.pageSize) {
                return (this.page - 1) * this.pageSize + key + 1;
            } else {
                return key + 1;
            }
        },
        getShow(item) {
            return typeof item.show === 'function'
                ? item.show()
                : item.show !== false
                ? true
                : false;
        },
        getDisabled(item){
            return typeof this.disabledCheck === 'function'
                ? this.disabledCheck(item)
                : this.disabledCheck
        },
        getContent(column,item) {
            if(column.filter){
                return column.filter(item[column.key], item) || '-'
            }else{
                return item[column.key] || item[column.key] === 0 ? item[column.key] : '-';
            }
        },
        changePage(page) {
            this.$emit('change-page', page);
        },
        showHtml(val){
            this.htmlModal.show = true;
            this.htmlModal.content = val;
        }
    },
    destroyed() {},
};
</script>

<style scoped>
.cardList /deep/ .ivu-card-body {
    padding: 10px 15px;
}
.cardList /deep/ .ivu-tooltip-rel .text-ellipsis{
    display: block;
}
.flex {
    display: flex !important;
    align-items: center;
}
.card-item {
    border: 2px solid #e7e7f1;
    margin-bottom: 15px;
    font-weight: bold;
}
.item-fist-line {
    display: flex;
    justify-content: space-between;
    width: 100%;
}
.line-left {
    flex: 1;
    min-width: 200px;
    overflow: hidden;
    display: flex;
    align-items: center;
}
.line-right {
    display: flex;
    flex-wrap: wrap;
    color: #a4a3c4;
}
.line-right .action {
    display: flex;
    justify-content: flex-end;
    align-items: center;
}
.line-right button.ivu-btn-text{
        border: none;
        background: none;
        outline: none;
        box-shadow: none;
}
.item-infos {
    display: flex;
    flex-wrap: wrap;
    margin-top: 7px;
    align-items: center;
    color: #a4a3c4;
}
.flex-center{
    display: flex;
    justify-content: center;
    align-items: center;
}
.h100 {
    height: 100%;
}
*[disabled] {
    cursor: not-allowed;
}
.ml20 {
    margin-left: 20px;
}
.mr20 {
    margin-right: 20px;
}
.pd0 {
    padding: 0px;
}
</style>
